Terraform Cloudでローカルからの「terraform plan」が遅い場合は.terraformignoreを活用しよう
はじめに
CX事業本部の佐藤智樹です。
今回は表題の通りTerraform Cloudを使っていてterraform plan
が遅くなっている方向けの記事です。
対象としては表題だけだとピンポイントな内容ですが、もしTerraform Cloudを使っている方ならサービスが少し大きくなったときに必ず当たる問題だと思うのでご一読ください。
念のため検証も行っているので良ければ最後まで読んでください。
結論
.terraformignore
ファイルを作成して、Terraformと関係ないファイルを中で指定してください。
.terraformignore とは
詳細は以下のTerraform Cloudに関するドキュメントの「Excluding Files from Upload with .terraformignore」に書かれています。
Terraform Cloud に stateファイルを置く場合、ローカルからも plan による差分確認が行えるよう設定ができます。この操作ではリポジトリにあるローカルのすべてのファイルがアップロードされるため、もしTerraformと関係のないファイルが大量にあるリポジトリの場合に plan の確認に大幅に時間がかかります。
例えば、モノレポ構成にしていてWebアプリケーションのコードが同じリポジトリに配置している場合に発生します。(というより筆者の場合上記の時に発生しました)
対処するためには.gitignore
ファイルなどと同じようにアップロードして欲しくないファイルを指定する必要があります。次章からは念のため本当に動作するのか検証してみます。
検証
検証自体は以下の流れで進めます。
- Terraform Cloudから plan 実行できる環境を準備
- ローカルからplan の実行時間を計測
- Terraformと無関係の大容量ファイルをリポジトリに追加
- ローカルからplan の実行時間を計測
- `.terraformignore`に3.で追加したファイルを無視するよう設定
- ローカルからplan の実行時間を計測
ファイルのアップロード時間に関係する内容なのでネットワークの接続状況などによってかなり変動します。なのであくまで参考程度にご確認ください。
1. Terraform Cloudから plan 実行できる環境を準備
まずはTerraform Cloud を実行できる環境を準備します。詳細な準備については以下の公式ドキュメントや弊社のブログをご確認ください。
以下のようにTerraform Cloudからplanやapply実行ができる環境を準備します。(※今回は検証のため簡易な設定にしていますが本来はアクセスキーやシークレットキーよりロールと外部IDの使用を推奨します。)
Terraform のコードは以下になります。
terraform { backend "remote" { hostname = "app.terraform.io" organization = "hogefuga-terraform" workspaces { name = "terraform_cloud_test" } } } provider "aws" { access_key = var.aws_access_key secret_key = var.aws_secret_key region = "ap-northeast-1" } resource "aws_vpc" "test-vpc" { cidr_block = "10.0.0.0/16" }
variable "aws_access_key" { type = string } variable "aws_secret_key" { type = string }
後は Terraform Cloud 上の Variables に設定を追加すればAWS環境へのアクセス準備が完了します。
2. ローカルからplan の実行時間を計測
準備ができたのでローカルから plan を実行します。今回は計測のため time
コマンドを使用します。
% time terraform plan ~省略~ No changes. Your infrastructure matches the configuration. Your configuration already matches the changes detected above. If you'd like to update the Terraform state to match, create and apply a refresh-only plan. terraform plan 0.93s user 0.56s system 3% cpu 41.642 total
大体コマンドを実行してコンソール上に結果が返ってくるまで40秒程度です。
3. Terraformと無関係の大容量ファイルをリポジトリに追加
次に不要な大容量ファイルを追加してみます。test
ディレクトリ配下にmkfile
コマンドで100MB程度のファイルを5つ生成します。
% mkdir test % cd test % mkfile 100m dummyfile % mkfile 100m dummyfile2 % mkfile 100m dummyfile3 % mkfile 100m dummyfile4 % mkfile 100m dummyfile5 % ls -l total 1024000 -rw------- 1 sato.tomoki hoge 104857600 5 30 17:12 dummyfile -rw------- 1 sato.tomoki hoge 104857600 5 30 17:15 dummyfile2 -rw------- 1 sato.tomoki hoge 104857600 5 30 17:15 dummyfile3 -rw------- 1 sato.tomoki hoge 104857600 5 30 17:15 dummyfile4 -rw------- 1 sato.tomoki hoge 104857600 5 30 17:15 dummyfile5
上記のファイルをリポジトリに追加しておきます。
% git add test/* % git commit -m "add dummy files" % git push
4. ローカルからplan の実行時間を計測
ファイルを追加して遅くなるのか確認します。
% time terraform plan ~省略~ No changes. Your infrastructure matches the configuration. Your configuration already matches the changes detected above. If you'd like to update the Terraform state to match, create and apply a refresh-only plan. terraform plan 2.29s user 0.75s system 3% cpu 1:23.96 total
1分20秒程度と目に見えて遅くなり始めました。
5. .terraformignoreに3.で追加したファイルを無視するよう設定
.terraformignore
ファイルを追加してファイルを無視するよう設定します。
test/
6. ローカルからplan の実行時間を計測
最後にローカルから実行して計測します。
% time terraform plan ~省略~ No changes. Your infrastructure matches the configuration. Your configuration already matches the changes detected above. If you'd like to update the Terraform state to match, create and apply a refresh-only plan. terraform plan 0.90s user 0.63s system 3% cpu 46.043 total
45秒前後なので.terraformignore
の効果が30~40秒程度あることが確認できます。
所感
検証結果だと500MBで30秒程度の差分でしたが、担当しているPJではソースが大きくなったためか数十分ほど待たないと plan の結果が返ってこないという悲惨な状況だったのでどなたかの役に立てばと思い記事にしました。どなたかのお役に立てば幸いです。